package cn.stylefeng.guns.modular.gridsystem.hechuang;

import cn.hutool.core.codec.Base64;
import cn.hutool.core.date.DatePattern;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.thread.ThreadUtil;
import cn.hutool.core.util.RandomUtil;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import cn.stylefeng.guns.modular.gridsystem.websocket.Message;
import lombok.extern.slf4j.Slf4j;
import org.java_websocket.client.WebSocketClient;
import org.java_websocket.handshake.ServerHandshake;

import javax.sound.sampled.AudioFileFormat;
import javax.sound.sampled.AudioFormat;
import javax.sound.sampled.AudioInputStream;
import javax.sound.sampled.AudioSystem;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.IOException;
import java.net.URI;
import java.util.Date;
import java.util.Timer;
import java.util.TimerTask;
import java.util.concurrent.ExecutorService;

@Slf4j
public class MyWebSocketClient extends WebSocketClient {
    ByteArrayOutputStream BYTE_BOS = new ByteArrayOutputStream();
    static long BYTE_SUM = 0;
    static int randomNumber = RandomUtil.randomInt(1000, 99999);
    static final String gatewayCode = "1ae8ccef0d668192c296a039e3299110";
    static final String channel = "1";
    static final String cmd = "START";
    static String WS_SERVICE_URL = "ws://192.168.31.232:82/ws/gateway/" + randomNumber;

    // private FramedConnection musicPlayer;
    /**
     * 初始化线程池，同时执行2个线程
     */
    private static ExecutorService executor = ThreadUtil.newExecutor(2);

    public static void main(String[] args) {
        //这里要求多线程操作
        MessageParam param1 = new MessageParam();
        final int randomNumber1 = RandomUtil.randomInt(1000, 99999);
        param1.setRandomNumber(randomNumber1);
        param1.setGatewayCode(gatewayCode);
        param1.setGatewayChannel("1");
        oneStart(param1);

        MessageParam param2 = new MessageParam();
        final int randomNumber2 = RandomUtil.randomInt(1000, 99999);
        param2.setRandomNumber(randomNumber2);
        param2.setGatewayCode(gatewayCode);
        param2.setGatewayChannel("2");
        oneStart(param2);

    }


    //static String message = "{\"from\":\"1566\",\"to\":\"1ae8ccef0d668192c296a039e3299110\",\"cmd\":\"START\",\"data\":{\"channel\":\"1\",\"type\":\"1\"}}";
    public MyWebSocketClient(URI serverUri) {
        super(serverUri);
    }

    //心跳
    private Timer timer;
    private static final int HEARTBEAT_INTERVAL = 300 * 1000; // 30秒

    private void startHeartbeat() {
        timer = new Timer();
        timer.scheduleAtFixedRate(new TimerTask() {
            @Override
            public void run() {
                send("heartbeat"); // 发送心跳消息
            }
        }, 0, HEARTBEAT_INTERVAL);
    }

    private void stopHeartbeat() {
        if (timer != null) {
            timer.cancel();
            timer = null;
        }
    }

    @Override
    public void onOpen(ServerHandshake handshakedata) {
        System.out.println("新连接已打开");
        // startHeartbeat();
    }

    @Override
    public void onMessage(String message) {
        System.out.println("接收到消息: " + message);
        // 处理接收到的消息
    }

    @Override
    public void onClose(int code, String reason, boolean remote) {
        System.out.println("连接已关闭");
        //  stopHeartbeat();
    }

    @Override
    public void onError(Exception ex) {
        System.out.println("连接已异常" + ex.getMessage());
        ex.printStackTrace();
        //    stopHeartbeat();
    }


    public static void oneStart(MessageParam param) {
        try {
            URI uri = new URI(param.getWsServiceUrl());
            MyWebSocketClient client = new MyWebSocketClient(uri) {
                @Override
                public void onOpen(ServerHandshake handshakedata) {
                    Message msg = new Message();
                    msg.setFrom(String.valueOf(param.getRandomNumber()));
                    msg.setTo(param.getGatewayCode());
                    msg.setCmd(param.getCmd());
                    JSONObject data = JSONUtil.parseObj(msg.getData());
                    data.set("channel", param.getGatewayChannel());
                    data.set("type", "1");
                    msg.setData(data);
                    String msgJson = JSONUtil.toJsonStr(msg);
                    System.out.println("发送的的message>>>>>>>>>>>>" + msgJson);
                    send(msgJson);
                }

                @Override
                public void onMessage(String message) {
                    // 处理接收到的消息
                    //   log.info("JAVA客户端接收的数据：{}", message);
                    //消息的处理
                    if (message.equals("OFFLINE")) {
                        System.out.println("本次链接出错啦！！");
                        return;
                    }
                    final Message entity = JSONUtil.toBean(message, Message.class);

                    JSONObject data = JSONUtil.parseObj(entity.getData());
                    String channel = data.getStr("channel");
                    String audio = data.getStr("audio");
                    String type = data.getStr("type");
                    byte[] bytes = Base64.decode(audio);

                    toAddFile(bytes);
                }

                @Override
                public void onClose(int code, String reason, boolean remote) {
                    System.out.println("连接已关闭");
                    //  stopHeartbeat();
                    // reconnect();
                }

                @Override
                public void onError(Exception ex) {
                    System.out.println("连接已异常" + ex.getMessage());
                    ex.printStackTrace();
                    //    stopHeartbeat();
                    // reconnect();
                }

            };
            client.connect(); // 连接到WebSocket服务器
            System.out.println("【" + param.getGatewayChannel() + "】  >>>>> 本次websocket 链接开始！");
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    public static int writeWav(byte[] audioData, File target) throws IOException {
        final File parent = target.getParentFile();
        if (!parent.exists()) {
            parent.mkdirs();
        }
        AudioFormat audioFormat = new AudioFormat(16000, 16, 1, true, false);
        try (ByteArrayInputStream bais = new ByteArrayInputStream(audioData);
             AudioInputStream ais = new AudioInputStream(bais, audioFormat, audioData.length / audioFormat.getFrameSize())) {
            //定义最终保存的文件名
            return AudioSystem.write(ais, AudioFileFormat.Type.WAVE, target);
        } catch (Exception e) {
            return -1;
        }
    }


    public void toAddFile(byte[] bytes) {
        try {
            if (BYTE_SUM >= 20 * 32000) {
                byte[] byteArray = BYTE_BOS.toByteArray();
                //下面将byte数组写成音频
                //空文件
                //  final int randomNumber2 = RandomUtil.randomInt(1000, 9999999);
                String wavName = DateUtil.format(new Date(), DatePattern.PURE_DATETIME_PATTERN);
                File file = new File("F:\\DEMO_TEST\\websocket\\" + wavName + ".wav");

                int ss = writeWav(byteArray, file);
                //System.out.println("ss>>>>>>>>>>>>>>" + ss);

                // File file = ToFileUtils.writeFileBytes(bytes, "F:\\DEMO_TEST\\websocket", ".wav");
                log.warn("JAVA客户端接收的文件全路径：{}", file.getAbsolutePath());

                //写完之后清空
                BYTE_SUM = 0;
                BYTE_BOS.reset();
            } else {
                BYTE_SUM += bytes.length;
                BYTE_BOS.write(bytes);
            }

        } catch (IOException e) {
            throw new RuntimeException(e);
        }

    }

}



